/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;

/**
 * @author Abahe
 */
public class Fading extends javax.microedition.midlet.MIDlet
                        implements CommandListener{

    private Command mExitCommand;

    public void startApp() {

        mExitCommand = new Command("Exit", Command.SCREEN, 0);
        TheCanvas tc = new TheCanvas();
        tc.addCommand(mExitCommand);
        tc.setCommandListener(this);
        Display d = Display.getDisplay(this);
        d.setCurrent(tc);
    }

    public void pauseApp() {

    }

    public void destroyApp(boolean unconditional) {

    }

    public void commandAction(Command c, Displayable d){
        notifyDestroyed();
    }
}

class TheCanvas extends Canvas
                implements Runnable{

    private Image mJavaImage;
    private Image mBgImage;
    private Image mBufferImage;

    private Graphics mGraphics;

    private boolean mTrucking = true;
    private boolean mUpdate = true;

    private int mAlpha = 0;
    private int mValue = 5;

    private int[]rawInt; // this is the array who will hold the image ARGB values.
                         // to do the blending we will change the Alpha value.

    private Runtime rt;

    public TheCanvas(){

        rt = Runtime.getRuntime(); // to get the amount of free memory.

        // Load images. Use mGraphics to draw on the backbuffer.
        mBufferImage = Image.createImage(getWidth(), getHeight());
        mGraphics = mBufferImage.getGraphics();
        try{
            mJavaImage = Image.createImage("/java.png");
            mBgImage = Image.createImage("/bg.png");
        }catch(Exception e){}

        // Allocate mamory for the image array.
        // Use the getRGB method to get all ARGB values from the image to the rawInt array.
        rawInt = new int[mJavaImage.getWidth() * mJavaImage.getHeight()];
        mJavaImage.getRGB(rawInt, 0, mJavaImage.getWidth(), 0, 0, mJavaImage.getWidth(), mJavaImage.getHeight());

        Thread t = new Thread(this);
        t.start();
    }

    // draw the image to the canvas.
    public void paint(Graphics g){
        g.drawImage(mBufferImage, 0, 0, 0);
        //g.drawString("freeMemory=" + String.valueOf(rt.freeMemory()), 0, 100, 0);
        mUpdate = true;
    }

    public void run() {
        while(mTrucking){
            if(mUpdate){
                // change the alpha value each loop. 255=opaque, 0=transparent.
                mAlpha+= mValue;
                if(mAlpha>=255)
                    mValue = mValue *-1;
                else if(mAlpha<=0)
                    mValue = mValue *-1;

                // Use the blend method in ImageEffect the change the Alpha value.
                // create a new Image from the new rawInt array.
                ImageEffect.blend(rawInt, mAlpha);
                Image fadingImage = Image.createRGBImage(rawInt, mJavaImage.getWidth(), mJavaImage.getHeight(), true);

                mGraphics.setColor(0xFFFFFF);
                mGraphics.fillRect(0, 0, getWidth(), getHeight());
                mGraphics.drawImage(mBgImage, 0, 0, 0);
                mGraphics.drawImage(fadingImage, 0, 10, 0);
                System.gc();

                mUpdate = false;
            }
            repaint();
        }
    }

}

class ImageEffect{

    // raw is the image array.
    public static void blend(int[] raw, int alphaValue, int maskColor, int dontmaskColor){
        int len = raw.length;

        // Start loop through all the pixels in the image.
        for(int i=0; i<len; i++){
            int a = 0;
            int color = (raw[i] & 0x00FFFFFF); // get the color of the pixel.
            if(maskColor==color){
                a = 0;
            }else if(dontmaskColor==color){
                a = 255;
            }else if(alphaValue>0){
                a = alphaValue;     // set the alpha value we vant to use 0-255.
            }

            a = (a<<24);    // left shift the alpha value 24 bits.
            // if color = 00000000 11111111 11111111 00000000
            // and alpha= 01111111 00000000 00000000 00000000
            // then c+a = 01111111 11111111 11111111 00000000
            // and the pixel will be blended.
            color += a;
            raw[i] = color;
        }
    }
    public static void blend(int[] raw, int alphaValue){
        blend(raw, alphaValue, 0xFFFFFFFF, 0xFFFFFFFF);
    }
}
